package cn.com.server.push;

import cn.com.common.*;
import cn.com.common.model.ProbeModel;
import cn.com.rpc.NettyChannel;
import cn.com.server.dict.AppDictionary;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import java.util.Set;
import java.util.concurrent.atomic.AtomicLong;

/**
 * @author jiaming
 */
public class AppPushService implements Push<ProbeModel> {

    protected static final Logger log = LogManager.getLogger();

    private AtomicLong atomicPushNumber = new AtomicLong(0);

    @Override
    public void push(ProbeModel model) {
        //获取注册中心上注册的client
        Set<RegistryInfo> appSet = AppDictionary.getAppRegistryInfo(model.getAppName());
        if (appSet == null || appSet.isEmpty()) {
            log.warn("未找到注册的服务：{},推送失败！", model.getAppName());
            return;
        }
        for (RegistryInfo registryInfo : appSet) {
            String host = registryInfo.getHost();
            //获取连接
            NettyChannel nettyChannel = NettyChannel.getNettyChannelByHost(host);
            if (nettyChannel != null) {
                if (nettyChannel.isConnected()) {
                    doPush(nettyChannel, model);
                } else {
                    log.warn("推送连接断开或已关闭，host：{}", host);
                }
            } else {
                log.warn("未找到appName：{}，host：{} 的长连接，key：{}推送失败", model.getAppName(), host, model.getKey());
            }
        }
    }

    private void doPush(NettyChannel nettyChannel, ProbeModel model) {
        Request request = new Request();
        Header header = new Header();
        header.setEventType(Constant.ONEWAY);
        header.setStatus(Constant.SUCCESS);
        header.setSerialType(Constant.PROTOBUF_SERIALIZE);
        header.setId(request.newId());
        request.setHeader(header);
        request.setData(model);
        nettyChannel.send(request, false);
        atomicPushNumber.incrementAndGet();
        if (atomicPushNumber.get() % 10000L == 0L) {
            log.info("push key number:{}", atomicPushNumber.get());
        }
    }

}